#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv)
{
	int server_fd, client_fd = -1;
	int server_len, client_len;
	fd_set inputs;
	int result;
	int i;
	int buflen;

	char buff[1024];
	struct sockaddr_in server_addr, client_addr;
	if (-1 == (server_fd = socket(AF_INET, SOCK_STREAM, 0)))
	{
		perror("socket");
		exit(-1);
	}

	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	server_addr.sin_port = htons(8000);
	server_len = sizeof (server_addr);
	if (-1 == bind(server_fd, (struct sockaddr *)&server_addr, server_len))
	{
		perror("bind");
		exit(-1);
	}

	if (-1 == listen(server_fd, 5))
	{
		perror("listen");
		exit(-1);
	}

	FD_ZERO(&inputs);
	FD_SET(0, &inputs);
	FD_SET(server_fd, &inputs);

	while(1) 
	{
		client_len = sizeof (client_addr);
		result = select(FD_SETSIZE, &inputs, 0, 0, 0);
		if (result < 0)
		{
			perror("select");
			continue;
		}

		for (i = 0; i < FD_SETSIZE && result > 0; i++)
		{
			if(FD_ISSET(i, &inputs) && result--)
				if (i == 0)
				{
					 buflen = read(i, buff, 1024);
						if (client_fd != -1)
							write(client_fd, buff, buflen);
				}
				else if (i == server_fd)
				{
					client_len = sizeof(client_addr);
					if (-1 == (client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len)))
					{
						perror("accept");
						continue;
					}
					FD_SET(client_fd, &inputs);
				}
				else
				{
					buflen = read(i, buff, 1024);
						write(1, buff, buflen);
				}
		}

		FD_SET(0, &inputs);
		FD_SET(server_fd, &inputs);
		if (-1 != client_fd)
			FD_SET(client_fd, &inputs);
	}

	return 0;
}
